package com.cyou.qb.system;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.cyou.nad.utils.LogObjectUtils;
import com.cyou.nad.utils.StringDataUtils;
import com.cyou.qb.common.domain.UserOperationLog;
import com.cyou.qb.constants.Constants;


/** 
 * @author luzhaoman
 *
 */
public class ServiceContext {

   
	/**登录用户上下文 */
   private UserContext userContext;

	/**
	 * 操作通过的程序方法
	 */
	private String operationMethod;
	
	/** 日志结果集*/
	private List<UserOperationLog> logList = new ArrayList<UserOperationLog>();
	
	public UserContext getUserContext() {
		return userContext;
	}

	public void setUserContext(UserContext userContext) {
		this.userContext = userContext;
	}

	public List<UserOperationLog> getLogList() {
		return logList;
	}

	public void setLogList(List<UserOperationLog> logList) {
		this.logList = logList;
	}

	public String getOperationMethod() {
		return operationMethod;
	}

	public void setOperationMethod(String operationMethod) {
		this.operationMethod = operationMethod;
	}
	/**
	 * 添加一条日志记录
	 * @param target 			操作记录的名称
	 * @param targetId			操作记录的id
	 * @param targetTable		操作的表名称
	 * @param memo				操作描述
	 * @param newDatas			操作后的数据
	 * @param oldDatas			操作前的数据
	 */
	public void addLog(String target,int targetId,String targetTable, String memo, Object[] newDatas,Object[] oldDatas)  {
		UserOperationLog operationLog = new UserOperationLog();
		operationLog.setTarget(target);
		operationLog.setTargetId(targetId);
		operationLog.setTargetTable(targetTable);
		operationLog.setMemo(memo);
		operationLog.setCreateDate(new Date());
		operationLog.setOpData(spellOperationData(newDatas,oldDatas));
		logList.add(operationLog);
	}

	/**
	 * 将处理的前后数据拼接成日志
	 * @param newDatas
	 * @param oldDatas
	 * @return
	 */
	private String spellOperationData(Object[] newDatas, Object[] oldDatas){
		
		if((null == newDatas || newDatas.length < 1 ) && (null == oldDatas || oldDatas.length < 1)){
			return null;
		}
		
		StringBuffer operationData = new StringBuffer();
		
		if(null == oldDatas || oldDatas.length < 1){
			//新增情况，只记录新的数据
			operationData.append("[new]");			
			for(Object newLogableObject : newDatas){
				operationData.append(LogObjectUtils.getLogString(newLogableObject));
			}	
			return dealLogLength(operationData.toString());
		}
		
		if(null == newDatas || newDatas.length < 1 ){
			//删除情况，只记录老的数据
			operationData.append("[old]");			
			for(Object oldLogableObject : oldDatas){
				operationData.append(LogObjectUtils.getLogString(oldLogableObject));
			}
			return dealLogLength(operationData.toString());
		}
		
		//既有老数据又有新数据的处理方式，挨个比较对应的对象，选出变更的属性
		
		int maxLegnth = newDatas.length > oldDatas.length ? newDatas.length : oldDatas.length;
		
		Object newData, oldData;
		for(int i=0; i< maxLegnth; i++){
			if(newDatas.length > i){
				newData = newDatas[i];
			}else{
				newData = null;
			}			
			if(oldDatas.length > i){
				oldData = oldDatas[i];
			}else{
				oldData = null;
			}
			if(null != newData && null != oldData){
				//比较对象
				if(newData.getClass().equals(oldData.getClass())){
					operationData.append("[update]");						
					operationData.append(LogObjectUtils.getDiffLogString(newData, oldData));
				}else{
					operationData.append("[new]");			
					operationData.append(LogObjectUtils.getLogString(newData));
					operationData.append("[old]");			
					operationData.append(LogObjectUtils.getLogString(oldData));
				}				
			}else if(null != newData && null == oldData){
				operationData.append("[new]");			
				operationData.append(LogObjectUtils.getLogString(newData));
			}else if(null == newData && null != oldData){
				operationData.append("[old]");			
				operationData.append(LogObjectUtils.getLogString(oldData));
			}else{
			}
			
		}
		
		return dealLogLength(operationData.toString());
	}
	/**
	 * 处理日志长度，如果超出MAX_LOGINFO_LENGTH，取前MAX_LOGINFO_LENGTH长度
	 * @param log
	 * @return
	 */
	private String dealLogLength(String log){
		if(null == log){
			return null;
		}
		return StringDataUtils.getFirstSubStringByByteLen(log.trim(), Constants.MAX_LOGINFO_BYTE_LENGTH);	
	}

}
